package com.fjut.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fjut.client.activity.CouponFeignClient;
import com.fjut.client.course.CourseFeignClient;
import com.fjut.client.userInfo.UserInfoFeignClient;
import com.fjut.exception.CustomException;
import com.fjut.mapper.OrderInfoMapper;
import com.fjut.model.activity.CouponInfo;
import com.fjut.model.order.OrderDetail;
import com.fjut.model.order.OrderInfo;
import com.fjut.model.user.UserInfo;
import com.fjut.model.vod.Course;
import com.fjut.service.OrderDetailService;
import com.fjut.service.OrderInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjut.utils.AuthContextHolder;
import com.fjut.utils.OrderNoUtils;
import com.fjut.vo.order.OrderFormVo;
import com.fjut.vo.order.OrderInfoQueryVo;
import com.fjut.vo.order.OrderInfoVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import static com.fjut.dateBase.CourseDescriptionField.COURSE_ID;
import static com.fjut.dateBase.OrderField.*;

/**
 * <p>
 * 订单表 订单表 服务实现类
 * </p>
 *
 * @author DengTianxun
 * @since 2023-03-09
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    private static final String TOTAL = "total";
    private static final String PAGE_COUNT = "pageCount";
    private static final String RECORDS = "records";
    private static final String COURSE_NAME = "courseName";

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private CouponFeignClient couponFeignClient;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Autowired
    private CourseFeignClient courseFeignClient;

    @Override
    public Map<String, Object> pageList(Page<OrderInfo> orderInfoPage, OrderInfoQueryVo orderInfoQueryVo) {
        if (orderInfoQueryVo == null) {
            return null;
        }
        //判断条件值是否为空，不为空，进行条件封装
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(orderInfoQueryVo.getOrderStatus())) {
            wrapper.eq(ORDER_STATUS, orderInfoQueryVo.getOrderStatus());
        }
        if (!StringUtils.isEmpty(orderInfoQueryVo.getUserId())) {
            wrapper.eq(USER_ID, orderInfoQueryVo.getUserId());
        }
        if (!StringUtils.isEmpty(orderInfoQueryVo.getOutTradeNo())) {
            wrapper.eq(OUT_TRADE_NO, orderInfoQueryVo.getOutTradeNo());
        }
        if (!StringUtils.isEmpty(orderInfoQueryVo.getPhone())) {
            wrapper.eq(PHONE, orderInfoQueryVo.getPhone());
        }
        if (!StringUtils.isEmpty(orderInfoQueryVo.getCreateTimeBegin())) {
            wrapper.ge(CREATE_TIME, orderInfoQueryVo.getCreateTimeBegin());
        }
        if (!StringUtils.isEmpty(orderInfoQueryVo.getCreateTimeEnd())) {
            wrapper.le(CREATE_TIME, orderInfoQueryVo.getCreateTimeEnd());
        }
        //调用实现条件分页查询
        baseMapper.selectPage(orderInfoPage, wrapper);

        //订单里面包含详情内容，封装详情数据，根据订单id查询详情
        orderInfoPage.getRecords().forEach(item -> {
            this.getOrderDetail(item);
        });

        //所有需要数据封装map集合，最终返回
        Map<String, Object> map = new HashMap<>();
        map.put(TOTAL, orderInfoPage.getTotal());
        map.put(PAGE_COUNT, orderInfoPage.getPages());
        map.put(RECORDS, orderInfoPage.getRecords());
        return map;
    }

    @Override
    public Long submitOrder(OrderFormVo orderFormVo) {
        Long courseId = orderFormVo.getCourseId();
        Long couponId = orderFormVo.getCouponId();
        Long userId = AuthContextHolder.getUserId();
        Course course = courseFeignClient.getClientCourseWxById(courseId);
        if (course == null) {
            throw new CustomException(400, "课程不存在");
        }
        UserInfo userInfo = userInfoFeignClient.getUserInfoById(userId);
        if (userInfo == null) {
            throw new CustomException(400, "用户不存在");
        }
        BigDecimal amount = new BigDecimal(0);
        if (couponId != null) {
            CouponInfo couponInfo = couponFeignClient.getClientCouponById(couponId);
            if (couponInfo == null) {
                throw new CustomException(400, "优惠券不存在");
            }
            amount = couponInfo.getAmount();
        }
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userId);
        orderInfo.setNickName(userInfo.getNickName());
        orderInfo.setPhone(userInfo.getPhone());
        orderInfo.setProvince(userInfo.getProvince());
        orderInfo.setOriginAmount(course.getPrice());
        orderInfo.setCouponReduce(amount);
        orderInfo.setFinalAmount(orderInfo.getOriginAmount().subtract(orderInfo.getCouponReduce()));
        orderInfo.setOutTradeNo(OrderNoUtils.getOrderNo());
        orderInfo.setTradeBody(course.getTitle());
        orderInfo.setOrderStatus("0");
        this.save(orderInfo);

        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderInfo.getId());
        orderDetail.setUserId(userId);
        orderDetail.setCourseId(courseId);
        orderDetail.setCourseName(course.getTitle());
        orderDetail.setCover(course.getCover());
        orderDetail.setOriginAmount(course.getPrice());
        orderDetail.setCouponReduce(new BigDecimal(0));
        orderDetail.setFinalAmount(orderDetail.getOriginAmount().subtract(orderDetail.getCouponReduce()));
        orderDetailService.save(orderDetail);

        if (null != orderFormVo.getCouponUseId()) {
            couponFeignClient.updateClientCouponInfo(orderFormVo.getCouponUseId(), orderInfo.getId());
        }

        return orderInfo.getId();
    }

    @Override
    public OrderInfoVo getOrderInfo(Long id) {
        OrderInfo orderInfo = baseMapper.selectById(id);
        OrderDetail orderDetail = orderDetailService.getById(id);
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        BeanUtils.copyProperties(orderInfo, orderInfoVo);
        orderInfoVo.setCourseId(orderDetail.getCourseId());
        orderInfoVo.setCourseName(orderDetail.getCourseName());
        return orderInfoVo;
    }

    @Override
    public Boolean updateOrderStatus(String outTradeNo) {
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(outTradeNo)) {
            wrapper.eq("out_trade_no", outTradeNo);
        }
        OrderInfo orderInfo = baseMapper.selectOne(wrapper);
        orderInfo.setOrderStatus("1");
        baseMapper.updateById(orderInfo);
        return true;
    }

    private OrderInfo getOrderDetail(OrderInfo orderInfo) {
        OrderDetail orderDetail = orderDetailService.getById(orderInfo.getId());
        if (orderDetail == null) {
            return null;
        }
        orderInfo.getParam().put(COURSE_NAME, orderDetail.getCourseName());
        return orderInfo;
    }

}
